/* mips.h */

/*
 * Define human readable registers, coprocessor 0 registers,
 * cause and status register masks, memory segment addresses, context record
 * offsets, and cache functions and register offsets.
 */

#ifndef	CONTEXT
#define	CONTEXT	64
#endif

/*
 * Human readable register names
 */

#define zero $0                /* wired zero                          */
#define AT   $1                /* asm temp--uppercase due to .set at  */
#define v0   $2                /* return value                        */
#define v1   $3
#define a0   $4                /* argument 0 to 3                     */
#define a1   $5
#define a2   $6
#define a3   $7
#define t0   $8                /* caller saved 0 to 7                 */
#define t1   $9
#define t2   $10
#define t3   $11
#define t4   $12
#define t5   $13
#define t6   $14
#define t7   $15
#define s0   $16               /* callee saved 0 to 7                */
#define s1   $17
#define s2   $18
#define s3   $19
#define s4   $20
#define s5   $21
#define s6   $22
#define s7   $23
#define t8   $24                /* caller saved 8 and 9               */
#define t9   $25
#define jp   $25                /* PIC jump register                  */
#define k0   $26                /* kernel scratch                     */
#define k1   $27
#define gp   $28                /* global pointer                     */
#define s8   $28                /* callee saved 8, alternative to gp  */
#define sp   $29                /* stack pointer                      */
#define fp   $30                /* frame pointer                      */
#define s9   $30                /* callee saved 9, alternative to fp  */
#define ra   $31                /* return address                     */

/*
 * Coprocessor 0 registers
 */

#define CP0_INDEX    $0  /* Index pointer into TLB                    */
#define CP0_RANDOM   $1  /* Random pointer into TLB                   */
#define CP0_ENTRYLO0 $2  /* Even page TLB entry                       */
#define CP0_ENTRYLO1 $3  /* Odd page TLB entry                        */
#define CP0_CONTEXT  $4  /* Hold PTE base and VPN on TLB exception    */
#define CP0_PGMASK   $5  /* Mask for virtual address on TLB matching  */
#define CP0_WIRED    $6  /* Boundary between random and wired entries */
#define CP0_BADVADDR $8  /* Bad address generated by TLB exceptions   */
#define CP0_COUNT    $9  /* Timer counter                             */
#define CP0_ENTRYHI  $10 /* Hi half of TLB (VPN+ASID)                 */
#define CP0_COMPARE  $11 /* interrupt when CP0_COUNT == CP0_COMPARE   */
#define CP0_STATUS   $12 /* Various run time processor information    */
#define CP0_CAUSE    $13 /* Identifies cause of interrupt/exception   */
#define CP0_EPC      $14 /* Return address after exception handling   */
#define CP0_PRID     $15 /* processor identification                  */
#define CP0_CONFIG   $16 /* configuration register (select 0, 1)      */
#define CP0_DIAG     $22 /* implementation dependent (diagnostic?)    */
#define CP0_TAGLO    $28
#define CP0_TAGHI    $29
#define CP0_ERREPC   $30

/*
 * Processor ID masks
 */
#define PRID_REV   0x000000FF   /* Revision                           */
#define PRID_CPU   0x0000FF00   /* CPU ID                             */

/*
 * Platform specific values and macros
 */

/* Processor revisions */
#define PRID_REV_QEMU       0x00
#define PRID_REV_WRT54G     0x29
#define PRID_REV_WRT54GL    0x08
#define PRID_REV_WRT350N    0x1A
#define PRID_REV_WRT160NL   0x74

#define PRID_CPU_BCM3302    0x9000
#define PRID_CPU_24K        0x9300


/*
 * Cause register interrupt masks
 */
#define CAUSE_EXC 0x0000007C    /* exception code bits                */
#define CAUSE_IRQ 0x0000FF00    /* interrupt request bits             */
#define CAUSE_EXC_SHIFT 2       /* exception code shift value         */
#define CAUSE_IRQ_SHIFT 8       /* interrupt request shift value      */
#define CAUSE_SW0 0x00000100    /* software interrupt                 */
#define CAUSE_SW1 0x00000200
#define CAUSE_HW0 0x00000400    /* eth0 interrupt                     */
#define CAUSE_HW1 0x00000800    /* serial interrupt                   */
#define CAUSE_HW2 0x00001000
#define CAUSE_HW3 0x00002000
#define CAUSE_HW4 0x00004000
#define CAUSE_HW5 0x00008000    /* timer interrupt                    */

/*
 * Status register masks
 */
#define STATUS_IE  0x00000001   /* Global interrupt enable            */
#define STATUS_EXL 0x00000002   /* Exception Level                    */
#define STATUS_ERL 0x00000004   /* Error Level                        */
#define STATUS_KSU 0x00000018   /* CPU Privilege Level                */
#define STATUS_SW0 CAUSE_SW0    /* Software interrupt enable          */
#define STATUS_SW1 CAUSE_SW1
#define STATUS_HW0 CAUSE_HW0    /* Hardware interrupt enable          */
#define STATUS_HW1 CAUSE_HW1    /* UART interrupt enable              */
#define STATUS_HW2 CAUSE_HW2
#define STATUS_HW3 CAUSE_HW3
#define STATUS_HW4 CAUSE_HW4
#define STATUS_HW5 CAUSE_HW5    /* Timer interrupt enable             */

/*
 * CPU Privilege Levels
 */
#define KSU_USER        0x00000010  /* User level privileges          */
#define KSU_SPRVSR      0x00000008  /* Supervisor privileges          */
#define KSU_KERNEL      0x00000000  /* Kernel privileges              */

/*
 * TLB Fields
 */
#define ENTRYHI_VPN2    0xFFFFF000  /* virtual page number            */
#define ENTRYHI_ASID    0x000000FF  /* addr space identifier (ASID)   */
#define ENTRYLO_PFN     0xFFFFFFC0  /* physical frame number          */
#define ENTRYLO_CCA     0x00000038  /* cache coherency attribute      */
#define ENTRYLO_DIRTY   0x04        /* dirty bit, write enable        */
#define ENTRYLO_VALID   0x02        /* valid bit                      */
#define ENTRYLO_GLOBL   0x01        /* global bit, ignore ASID        */

#define CONTEXT_BADVPN  0x00FFFFF0

/*
 * Define kernel memory segments for MIPS32 processors
 */
#define KUSEG_BASE 0x00000000   /* userspace mapped base              */
#define KUSEG_SIZE 0x80000000   /* userspace mapped (2 GB)            */
#define KSEG0_BASE 0x80000000   /* kernel unmapped, cached base       */
#define KSEG0_SIZE 0x20000000   /* kernel unmapped, cahced (512 MB)   */
#define KSEG1_BASE 0xA0000000   /* kernel unmapped, uncached base     */
#define KSEG1_SIZE 0x20000000   /* kernel unmapped, uncached (512 MB) */
#define KSEG2_BASE 0xC0000000   /* kernel mapped base                 */
#define KSEG2_SIZE 0x40000000   /* kernel mapped (1 GB)               */
#define PMEM_MASK  0x1FFFFFFF   /* physical memory address mask       */

#define addressk2p(a)	((a) & PMEM_MASK)
#define addressp2k(a)	(((a) & PMEM_MASK) | KSEG0_BASE)
#define addressp2k1(a)	(((a) & PMEM_MASK) | KSEG1_BASE)

/*
 * Context record offsets
 */
/* #define CONTEXT 64 */        /* context record size in bytes       */
/* context record size in words */
#define CONTEXT_WORDS (CONTEXT / sizeof(int32))

#define RA_CON  (CONTEXT - 8)   /* return address                     */
#define S9_CON  52              /* callee saved registers             */
#define S8_CON  48
#define S7_CON  44
#define S6_CON  40
#define S5_CON  36
#define S4_CON  32
#define S3_CON  28
#define S2_CON  24
#define S1_CON  20
#define S0_CON  16

/*
 * Cache register locations within the Config1 register
 */
#define CONFIG1_IS    22        /* instruction cache                  */
#define CONFIG1_IL    19
#define CONFIG1_IA    16
#define CONFIG1_DS    13        /* data cache                         */
#define CONFIG1_DL    10
#define CONFIG1_DA     7
#define CONFIG1_MASK   7        /* value mask                         */

/*
 * Cache functions
 */
#define INDEX_STORE_TAG_I  0x8  /* invalidate instruction cache tag   */
#define FILL_I_CACHE       0x14 /* fill instruction cache             */
#define INDEX_STORE_TAG_D  0x9  /* invalidate data cache tag          */
